package com.ca.project.Server.Modules.UserWeb.Service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ca.project.Server.Modules.UserInfo.Entity.UserInfo;
import com.ca.project.Server.Modules.UserInfo.Service.UserInfoService;
import com.ca.project.Server.Modules.UserWeb.Context.WebUserLoginContext;
import com.ca.project.Server.Modules.UserWeb.Context.WebUserQuestionContext;
import com.ca.project.Server.Modules.UserWeb.Context.WebUserRegisterContext;
import com.ca.project.Server.Modules.UserWeb.Converter.UserWebConverter;
import com.ca.project.Server.Modules.UserWeb.Entity.UserWeb;
import com.ca.project.Server.Modules.UserWeb.Service.UserWebService;
import com.ca.project.Server.Modules.UserWeb.Mapper.UserWebMapper;
import com.ca.project.core.Exception.BusinessException;
import com.ca.project.core.Exception.FrameworkException;
import com.ca.project.core.Respond.R;
import com.ca.project.core.Util.IdUtil;
import com.ca.project.core.Util.PasswordUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * @author ASUS
 * @description 针对表【user_web】的数据库操作Service实现
 * @createDate 2024-12-30 18:16:31
 */
@Service
public class UserWebServiceImpl extends ServiceImpl<UserWebMapper, UserWeb> implements UserWebService {

    @Autowired
    private UserWebConverter userWebConverter;

    @Autowired
    private UserInfoService userInfoService;

    /**
     * 用户注册
     * 1.先去找user_web表是否有该学号，存在则更新时间，不存在则注册
     * 2.再去找user_info表是否存在该学号的信息
     *
     * @param webUserRegisterContext
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> register(WebUserRegisterContext webUserRegisterContext) {
        String stuNum = webUserRegisterContext.getStu_num();
        UserWeb entity = findUserExist(stuNum);
        HashMap<String, Object> map = new HashMap<>();
        if (Objects.isNull(entity)) {
            assembleUserWeb(webUserRegisterContext);
            doRegister(webUserRegisterContext);
            UserInfo userInfo = userInfoService.getUserInfo(stuNum);
            if (StringUtils.isBlank(userInfo.getDormmun()) &&
                    StringUtils.isBlank(userInfo.getPhone()) &&
                    StringUtils.isBlank(userInfo.getRealname()) ||
                    StringUtils.isBlank(entity.getQuestion())) {
                map.put("code", 2);
                map.put("message", "该用户已注册，但未填写密保问题与答案");
            } else {
                map.put("code", 0);
                map.put("message", "注册成功");
            }
        } else {
            map.put("code", 3);
            map.put("message", "该用户已注册请前往登录页面");
        }
        return map;
    }

    /**
     * 更新密保问题答案
     *
     * @param webUserQuestionContext
     */
    @Override
    public void updateQuestion(WebUserQuestionContext webUserQuestionContext) {
        UpdateWrapper<UserWeb> wrapper = new UpdateWrapper<>();
        wrapper.eq("stu_num", webUserQuestionContext.getStu_num());
        wrapper.set("question", webUserQuestionContext.getQuestion());
        wrapper.set("answer", webUserQuestionContext.getAnswer());
        boolean success = baseMapper.update(null, wrapper) > 0;
        if (!success) {
            throw new BusinessException("更新失败");
        }
    }

    /**
     * 用户登录
     *
     * @param webUserLoginContext
     */
    @Override
    public void login(WebUserLoginContext webUserLoginContext) {
        UserWeb entity = findUserExist(webUserLoginContext.getStu_num());
        if (Objects.isNull(entity))
            throw new BusinessException("该用户未注册");
        CheckUserLogin(webUserLoginContext, entity);
    }


/************************************************private***************************************************************/
    /**
     * 查找用户是否存在
     *
     * @param Stu_num
     * @return
     */
    private UserWeb findUserExist(String Stu_num) {
        QueryWrapper<UserWeb> wrapper = new QueryWrapper<>();
        wrapper.eq("stu_num", Stu_num);
        return getOne(wrapper);
    }

    /**
     * 实体转换
     *
     * @param webUserRegisterContext
     */
    private void assembleUserWeb(WebUserRegisterContext webUserRegisterContext) {
        UserWeb entity = userWebConverter.WebUserRegisterContext2UserWeb(webUserRegisterContext);
        String salt = PasswordUtil.getSalt();
        try {
            String dbPassword = PasswordUtil.encryptPassword(salt, webUserRegisterContext.getPassword());
            final Long userId = IdUtil.get();
            entity.setId(userId);
            entity.setStuNum(webUserRegisterContext.getStu_num());
            entity.setSalt(salt);
            entity.setPassword(dbPassword);
            entity.setCreateTime(new Date());
            entity.setUpdateTime(new Date());
        } catch (Exception e) {
            throw new FrameworkException(e.getMessage());
        } finally {
            webUserRegisterContext.setEntity(entity);
        }
    }

    /**
     * 注册业务
     *
     * @param webUserRegisterContext
     */
    private void doRegister(WebUserRegisterContext webUserRegisterContext) {
        UserWeb entity = webUserRegisterContext.getEntity();
        try {
            if (!save(entity))
                throw new BusinessException("用户注册失败");
        } catch (DuplicateKeyException duException) {
            throw new BusinessException("该用户名已经注册");
        }
    }

    /**
     * 校验用户登录
     *
     * @param webUserLoginContext
     */
    private void CheckUserLogin(WebUserLoginContext webUserLoginContext, UserWeb entity) {
        String password = webUserLoginContext.getPassword();
        String stuNum = webUserLoginContext.getStu_num();
        String stu_num = entity.getStuNum();
        String salt = entity.getSalt();

        String encPassword = PasswordUtil.encryptPassword(salt, password);
        String dbPassword = entity.getPassword();
        if (!Objects.equals(encPassword, dbPassword) &&
                !Objects.equals(stuNum, stu_num))
            throw new BusinessException("密码信息不正确");
    }
}




